home *** CD-ROM | disk | FTP | other *** search
- Subject: v11i057: Mail user's shell, Part07/12
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: island!argv@Sun.COM (Dan Heller)
- Posting-number: Volume 11, Issue 57
- Archive-name: mush5.7/Part07
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 7 (of 12)."
- # Contents: commands.c misc.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'commands.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'commands.c'\"
- else
- echo shar: Extracting \"'commands.c'\" \(19548 characters\)
- sed "s/^X//" >'commands.c' <<'END_OF_FILE'
- X/* @(#)cmds.c (c) copyright 10/18/86 (Dan Heller) */
- X
- X#include "mush.h"
- X
- X/*
- X * Note that all of the routines in here act upon and return 0 or -1.
- X * if -1, then the main loop will clear message lists.
- X */
- X
- Xstruct cmd cmds[] = {
- X#ifdef SIGSTOP
- X { "stop", stop },
- X#endif SIGSTOP
- X { "?", question_mark },{ "sh", sh },
- X { "alias", do_alias }, { "unalias", do_alias },
- X { "expand", do_alias }, { "cmd", do_alias },
- X { "uncmd", do_alias }, { "from", do_from },
- X { "un_hdr", do_alias }, { "my_hdr", do_alias },
- X { "fkey", do_alias }, { "unfkey", do_alias },
- X { "set", set }, { "unset", set },
- X { "ignore", set }, { "unignore", set },
- X { "version", do_version }, { "help", print_help },
- X { "pick", do_pick }, { "sort", sort },
- X { "next", readmsg }, { "previous", readmsg },
- X { "type", readmsg }, { "print", readmsg },
- X { "history", disp_hist }, { "top", readmsg },
- X { "saveopts", save_opts }, { "source", source },
- X { "headers", do_hdrs }, { "ls", ls },
- X { "folder", folder }, { "update", folder },
- X { "cd", cd }, { "pwd", cd },
- X { "exit", quit }, { "quit", quit },
- X { "write", save_msg }, { "save", save_msg },
- X { "copy", save_msg }, { "folders", folders },
- X#ifdef CURSES
- X { "curses", curses_init }, { "bind", bind_it }, { "unbind", bind_it },
- X#endif CURSES
- X { "preserve", preserve }, { "unpreserve", preserve },
- X { "replyall", respond }, { "replysender", respond },
- X { "delete", delete }, { "undelete", delete },
- X { "mail", do_mail }, { "echo", do_echo },
- X { "lpr", lpr }, { "alternates", alts },
- X { NULL, quit }
- X};
- X
- Xstruct cmd ucb_cmds[] = {
- X { "t", readmsg }, { "n", readmsg }, { "p", readmsg },
- X { "+", readmsg }, { "-", readmsg },
- X { "x", quit }, { "q", quit },
- X { ":a", do_hdrs }, { ":d", do_hdrs },
- X { ":o", do_hdrs }, { ":u", do_hdrs }, { ":n", do_hdrs },
- X { "z", do_hdrs }, { "z-", do_hdrs }, { "z+", do_hdrs },
- X { "h", do_hdrs }, { "H", do_hdrs },
- X { "f", do_from }, { "m", do_mail }, { "alts", alts },
- X { "d", delete }, { "dt", delete }, { "dp", delete },
- X { "u", delete }, { "fo", folder },
- X { "s", save_msg }, { "co", save_msg },
- X { "pre", preserve }, { "w", save_msg },
- X { "R", respond }, { "r", respond },
- X { "reply", respond }, { "respond", respond },
- X { NULL, quit }
- X};
- X
- Xstruct cmd hidden_cmds[] = {
- X { "debug", toggle_debug }, { "open", nopenfiles },
- X { "flags", msg_flags }, { "stty", my_stty },
- X { "setenv", Setenv }, { "unsetenv", Unsetenv },
- X { "printenv", Printenv },
- X { NULL, quit }
- X};
- X
- Xtoggle_debug(argc, argv)
- Xchar **argv;
- X{
- X if (argc < 2) /* no value -- toggle "debug" (off/on) */
- X debug = !debug;
- X else
- X debug = atoi(*++argv);
- X print("debugging value: %d\n", debug);
- X return -1;
- X}
- X
- Xstatic
- Xsorter(cmd1, cmd2)
- Xregister struct cmd *cmd1, *cmd2;
- X{
- X return strcmp(cmd1->command, cmd2->command);
- X}
- X
- Xsort_commands()
- X{
- X qsort((char *)cmds, sizeof(cmds)/sizeof(struct cmd)-1,
- X sizeof(struct cmd), sorter);
- X}
- X
- X/* if + was specified, then print messages without headers.
- X * n or \n (which will be NULL) will print next unread or undeleted message.
- X */
- Xreadmsg(x, argv, list)
- Xregister char **argv, list[];
- X{
- X register char *p = x? *argv : NULL;
- X register long flg = 0;
- X
- X if (x && *++argv && !strcmp(*argv, "-?"))
- X return help(0, "readmsg", cmd_help);
- X#ifdef NOT_NOW
- X if (ison(glob_flags, IS_GETTING)) {
- X print("Finish editing your letter first.\n");
- X return -1;
- X }
- X#endif NOT_NOW
- X if (!msg_cnt) {
- X print("No messages.\n");
- X return -1;
- X }
- X if (x && !strcmp(p, "top"))
- X turnon(flg, TOP);
- X if (p && (*p == '+')) {
- X turnon(flg, NO_PAGE);
- X turnon(flg, NO_HEADER);
- X }
- X if (x && (x = get_msg_list(argv, list)) == -1)
- X return -1;
- X else if (x == 0) { /* no arguments were parsed (or given) */
- X /* get_msg_list sets current msg on */
- X unset_msg_bit(list, current_msg);
- X /* most commands move to the "next" message. type and print don't */
- X if ((!p || !*p || *p == 'n' || *p == '+') && current_msg < msg_cnt &&
- X isoff(msg[current_msg].m_flags, UNREAD))
- X current_msg++;
- X if (p && (*p == '-' || !strcmp(p, "previous"))) {
- X while (--current_msg >= 0 && ison(msg[current_msg].m_flags, DELETE))
- X ;
- X if (current_msg < 0) {
- X print("No previous message.\n");
- X current_msg = 0;
- X return -1;
- X }
- X } else {
- X /*
- X * To be compatible with ucb-mail, find the next available unread
- X * message. Stop at the end (don't wrap). Not the greatest way to
- X * do it, but people complain if it doesn't do it.
- X */
- X#ifdef NOT_ANYMORE
- X if (current_msg == msg_cnt) /* wrap around */
- X current_msg = 0;
- X#endif NOT_ANYMORE
- X /* "type" or "print" prints the current only -- "next" goes on.. */
- X if (!p || !*p || *p == 'n')
- X while (current_msg < msg_cnt &&
- X ison(msg[current_msg].m_flags, DELETE))
- X current_msg++;
- X if (current_msg >= msg_cnt) {
- X print("No more messages.\n");
- X current_msg = msg_cnt - 1;
- X return -1;
- X }
- X }
- X set_msg_bit(list, current_msg);
- X }
- X /* If we're piping messages, just return the message list */
- X if (ison(glob_flags, DO_PIPE))
- X return 0;
- X current_msg = 0;
- X for (x = 0; x < msg_cnt; x++)
- X if (msg_bit(list, x)) {
- X current_msg = x;
- X#ifdef SUNTOOL
- X if (istool > 1) {
- X read_mail(NO_ITEM, 0, NO_EVENT);
- X return 0;
- X }
- X#endif SUNTOOL
- X display_msg(x, flg);
- X }
- X return 0;
- X}
- X
- Xpreserve(n, argv, list)
- Xregister int n; /* no use for argc, so use space for a local variable */
- Xregister char **argv, list[];
- X{
- X register int unpre;
- X
- X unpre = !strncmp(*argv, "un", 2);
- X if (*++argv && !strcmp(*argv, "-?"))
- X return help(0, "preserve_help", cmd_help);
- X if (get_msg_list(argv, list) == -1)
- X return -1;
- X for (n = 0; n < msg_cnt; n++)
- X if (msg_bit(list, n))
- X if (unpre)
- X turnoff(msg[n].m_flags, PRESERVE);
- X else {
- X turnon(msg[n].m_flags, PRESERVE);
- X turnoff(msg[n].m_flags, DELETE);
- X }
- X if (istool)
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X return 0;
- X}
- X
- Xlpr(n, argv, list)
- Xregister int n; /* no use for argc, so use its address space for a variable */
- Xregister char **argv, list[];
- X{
- X register FILE *pp;
- X register long flags = 0;
- X char print_cmd[128], *printer, c, *cmd;
- X int total = 0, (*oldint)(), (*oldquit)();
- X
- X turnon(flags, NO_IGNORE);
- X if (!(printer = do_set(set_options, "printer")) || !*printer)
- X printer = DEF_PRINTER;
- X while (argv && *++argv && **argv == '-') {
- X n = 1;
- X while (c = argv[0][n++])
- X switch(c) {
- X case 'n': turnon(flags, NO_HEADER);
- X when 'h': turnoff(flags, NO_IGNORE);
- X when 'P': case 'd':
- X if (!argv[0][n]) {
- X print("specify printer!\n");
- X return -1;
- X }
- X printer = argv[0] + n;
- X n += strlen(printer);
- X otherwise: return help(0, "lpr", cmd_help);
- X }
- X }
- X if (get_msg_list(argv, list) == -1)
- X return -1;
- X
- X if (cmd = do_set(set_options, "print_cmd"))
- X (void) strcpy(print_cmd, cmd);
- X else
- X#ifdef SYSV
- X (void) sprintf(print_cmd, "%s -d%s", LPR, printer);
- X#else
- X (void) sprintf(print_cmd, "%s -P%s", LPR, printer);
- X#endif SYSV
- X Debug("print command: %s\n", print_cmd);
- X if (!(pp = popen(print_cmd, "w"))) {
- X error("cannot print");
- X return -1;
- X }
- X on_intr();
- X for (n = 0; isoff(glob_flags, WAS_INTR) && n < msg_cnt; n++) {
- X if (msg_bit(list, n)) {
- X if (total++)
- X fputc('\f', pp); /* send a formfeed for multiple copies */
- X print("printing message %d...", n+1);
- X print_more("(%d lines)\n", copy_msg(n, pp, flags));
- X }
- X }
- X off_intr();
- X (void) pclose(pp);
- X print_more("%d message%s printed ", total, (total==1)? "": "s");
- X if (cmd)
- X print_more("through \"%s\".\n", cmd);
- X else
- X print_more("at \"%s\".\n", printer);
- X return 0;
- X}
- X
- X/* save [msg_list] [file] */
- Xsave_msg(n, argv, list) /* argc isn't used, so use space for variable 'n' */
- Xregister char **argv, list[];
- X{
- X register FILE *mail_fp;
- X register char *file = NULL, *mode, firstchar = **argv, *tmp;
- X int msg_number, force;
- X long flg = 0;
- X
- X if (*++argv && !strcmp(*argv, "-?"))
- X return help(0, "save_help", cmd_help);
- X if (force = (*argv && !strcmp(*argv, "!")))
- X argv++;
- X if ((n = get_msg_list(argv, list)) == -1)
- X return -1;
- X argv += n;
- X if (*argv && *(file = *argv) == '\\')
- X file++;
- X else if (!file) {
- X /* if no filename specified, save in ~/mbox */
- X if (firstchar == 'w') {
- X /* mbox should have headers. If he really wants it, specify it */
- X print("Must specify file name for 'w'\n");
- X return -1;
- X }
- X if (!(file = do_set(set_options, "mbox")) || !*file)
- X file = DEF_MBOX;
- X }
- X n = 1; /* tell getpath to ignore no such file or directory */
- X tmp = getpath(file, &n);
- X if (n < 0) {
- X print("%s: %s\n", file, tmp);
- X return -1;
- X } else if (n) {
- X print("%s is a directory\n", file);
- X return -1;
- X }
- X file = tmp;
- X if (force || access(file, 0))
- X mode = "w", force = 0;
- X else
- X mode = "a";
- X
- X if (!(mail_fp = fopen(file, mode))) {
- X error("cannot save in \"%s\"", file);
- X return -1;
- X }
- X#ifdef SUNTOOL
- X if (istool)
- X lock_cursors();
- X#endif SUNTOOL
- X turnon(flg, NO_IGNORE);
- X if (firstchar == 'w')
- X turnon(flg, NO_HEADER);
- X else
- X turnon(flg, UPDATE_STATUS);
- X if (do_set(set_options, "keepsave"))
- X firstchar = 'c';
- X for (n = msg_number = 0; msg_number < msg_cnt; msg_number++)
- X if (msg_bit(list, msg_number)) {
- X print("%sing msg %d... ",
- X (firstchar == 's')? "Sav" : "Writ", msg_number+1);
- X print_more("(%d lines)\n", copy_msg(msg_number, mail_fp, flg));
- X /* only mark "deleted" if mailfile is /usr/spool/mail and
- X * we're not "copying. If keepsave is set, then firstchar
- X * will have already been changed to 'c'
- X */
- X if (is_spool(mailfile) && firstchar != 'c')
- X turnon(msg[msg_number].m_flags, DELETE);
- X n++;
- X }
- X fclose(mail_fp);
- X print_more("%s %d msg%s to %s\n",
- X (*mode == 'a')? "Appended" : "Saved", n, (n != 1)? "s": "", file);
- X if (is_spool(mailfile))
- X turnon(glob_flags, DO_UPDATE);
- X#ifdef SUNTOOL
- X if (istool) {
- X unlock_cursors();
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X }
- X#endif SUNTOOL
- X return 0;
- X}
- X
- Xrespond(n, argv, list)
- Xregister int n; /* no use for argc, so use its address space for a variable */
- Xregister char **argv, *list;
- X{
- X register char *cmd = *argv;
- X char list1[MAXMSGS_BITS];
- X
- X if (*++argv && !strcmp(*argv, "-?"))
- X return help(0, "respond_help", cmd_help);
- X if ((n = get_msg_list(argv, list)) == -1)
- X return -1;
- X /* make into our own list so ~: commands don't overwrite this list */
- X bitput(list, list1, MAXMSGS, =);
- X /* back up one arg to replace "cmd" in the new argv[0] */
- X argv += (n-1);
- X if (!strcmp(cmd, "replyall"))
- X Upper(*cmd);
- X strdup(argv[0], cmd);
- X current_msg = -1;
- X for (n = 0; n < msg_cnt; n++)
- X if (msg_bit(list1, n)) {
- X if (current_msg > -1 && istool) {
- X print("tool mode can not respond to multiple messages.");
- X continue;
- X }
- X current_msg = n;
- X set_isread(n);
- X if (do_mail(1, argv) == -1) /* do_mail doesn't look at argc */
- X return -1;
- X }
- X return 0;
- X}
- X
- X/* cd to a particular directory specified by "p" */
- Xcd(x, argv) /* argc, unused -- use space for a non-register variable */
- Xregister char **argv;
- X{
- X char *tmp, cwd[128], *p = argv[1];
- X#ifdef SYSV
- X char *getcwd();
- X#else
- X char *getwd();
- X#endif SYSV
- X int err = 0;
- X
- X if (!strcmp(*argv, "pwd")) {
- X p = do_set(set_options, "cwd");
- X if (p && *p) {
- X print("%s\n", p);
- X return -1;
- X }
- X }
- X if (!p || !*p)
- X p = (**argv == 'p')? "." : "~";
- X x = 0;
- X tmp = getpath(p, &x);
- X if (x == -1)
- X print("%s: %s.\n", p, tmp), err++;
- X else if (!x)
- X print("%s: not a directory.\n", tmp), err++;
- X else if (chdir(tmp))
- X error("can't chdir to %s", tmp), err++;
- X#ifdef SYSV
- X if (getcwd(cwd, 128) == NULL)
- X#else
- X if (getwd(cwd) == NULL)
- X#endif SYSV
- X print("can't get cwd: %s.\n", cwd), err++;
- X else {
- X char **new_argv, buf[256];
- X (void) sprintf(buf, "set cwd = \"%s\"", cwd);
- X Debug("%s\n", buf);
- X if (new_argv = mk_argv(buf, &x, 1))
- X (void) add_option(&set_options, new_argv), free_vec(new_argv);
- X }
- X if (istool || iscurses || err) {
- X if (err)
- X turnon(glob_flags, CONT_PRNT);
- X print("Working dir: %s\n", cwd);
- X }
- X return -1;
- X}
- X
- Xquit(argc, argv)
- Xchar **argv;
- X{
- X if (argc > 1 && !strcmp(argv[1], "-?"))
- X return help(0, "quit_help", cmd_help);
- X if ((!argc || (*argv && **argv == 'q')) && ison(glob_flags, DO_UPDATE)
- X && !copyback())
- X return -1;
- X#ifdef CURSES
- X if (iscurses) {
- X /* we may already be on the bottom line; some cases won't be */
- X move(LINES-1, 0), refresh();
- X }
- X#endif CURSES
- X cleanup(0);
- X#ifdef lint
- X return 0;
- X#endif lint
- X}
- X
- Xdelete(argc, argv, list)
- Xregister int argc;
- Xregister char **argv, list[];
- X{
- X register int prnt_next, undel = argc && **argv == 'u';
- X
- X prnt_next = (argv && (!strcmp(*argv, "dt") || !strcmp(*argv, "dp")));
- X
- X if (argc && *++argv && !strcmp(*argv, "-?")) {
- X print("usage: delete/undelete [msg_list]\n");
- X return -1;
- X }
- X
- X if (get_msg_list(argv, list) == -1)
- X return -1;
- X for (argc = 0; argc < msg_cnt; argc++)
- X if (msg_bit(list, argc))
- X if (undel)
- X turnoff(msg[argc].m_flags, DELETE);
- X else
- X turnon(msg[argc].m_flags, DELETE);
- X
- X /* only if current_msg has been affected && not in curses mode */
- X if (prnt_next == 0 && !iscurses && msg_bit(list, current_msg))
- X prnt_next = !!do_set(set_options, "autoprint"); /* change to boolean */
- X
- X turnon(glob_flags, DO_UPDATE);
- X
- X /* goto next available message if current was just deleted.
- X * If there are no more messages, turnoff prnt_next.
- X */
- X if (!iscurses && !undel && ison(msg[current_msg].m_flags, DELETE) &&
- X !next_msg(FALSE, DELETE) && prnt_next)
- X prnt_next = 0;
- X
- X if (prnt_next)
- X display_msg(current_msg, (long)0);
- X if (istool)
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X return 0;
- X}
- X
- X/*
- X * historically from the "from" command in ucb-mail, this just prints
- X * the composed header of the messages set in list or in pipe.
- X */
- Xdo_from(n, argv, list)
- Xchar **argv, list[];
- X{
- X int inc_cur_msg = 0;
- X
- X if (argv && *++argv && !strcmp(*argv, "-?"))
- X return help(0, "from", cmd_help);
- X if (argv && *argv && (!strcmp(*argv, "+") || !strcmp(*argv, "-")))
- X if (!strcmp(*argv, "+")) {
- X if (!*++argv && current_msg < msg_cnt-1)
- X current_msg++;
- X inc_cur_msg = 1;
- X } else if (!strcmp(*argv, "-")) {
- X if (!*++argv && current_msg > 0)
- X current_msg--;
- X inc_cur_msg = -1;
- X }
- X if (get_msg_list(argv, list) == -1)
- X return -1;
- X for (n = 0; n < msg_cnt; n++)
- X if (msg_bit(list, n)) {
- X wprint("%s\n", compose_hdr(n));
- X /* if -/+ given, set current message pointer to this message */
- X if (inc_cur_msg) {
- X current_msg = n;
- X /* if - was given, then set to first listed message.
- X * otherwise, + means last listed message -- let it go...
- X */
- X if (inc_cur_msg < 0)
- X inc_cur_msg = 0;
- X }
- X }
- X return 0;
- X}
- X
- X/*
- X * Do an ls from the system.
- X * Read from a popen and use wprint in case the tool does this command.
- X * The folders command uses this command.
- X */
- Xls(x, argv)
- Xchar **argv;
- X{
- X register char *p, *tmp;
- X char buf[128];
- X register FILE *pp;
- X
- X if (*++argv && !strcmp(*argv, "-?"))
- X return help(0, "ls", cmd_help);
- X if (!(p = do_set(set_options, "lister")))
- X p = "";
- X (void) sprintf(buf, "%s -C%s ", LS_COMMAND, p);
- X p = buf+strlen(buf);
- X for ( ; *argv; ++argv) {
- X x = 0;
- X if (**argv != '-')
- X tmp = getpath(*argv, &x);
- X else
- X tmp = *argv;
- X if (x == -1) {
- X wprint("%s: %s\n", *argv, tmp);
- X return -1;
- X }
- X p += strlen(sprintf(p, " %s", tmp));
- X }
- X if (!(pp = popen(buf, "r"))) {
- X error(buf);
- X return -1;
- X }
- X turnon(glob_flags, IGN_SIGS);
- X while (fgets(buf, 127, pp))
- X wprint(buf);
- X (void) pclose(pp);
- X turnoff(glob_flags, IGN_SIGS);
- X return 0;
- X}
- X
- Xsh(un_used, argv)
- Xchar **argv;
- X{
- X register char *p;
- X char buf[128];
- X
- X if (istool > 1 || *++argv && !strcmp(*argv, "-?"))
- X return help(0, "shell", cmd_help);
- X if (!(p = do_set(set_options, "shell"))
- X && !(p = do_set(set_options, "SHELL")))
- X p = DEF_SHELL;
- X if (!*argv)
- X (void) strcpy(buf, p);
- X else
- X (void) argv_to_string(buf, argv);
- X echo_on();
- X (void) system(buf);
- X echo_off();
- X return 0;
- X}
- X
- Xquestion_mark(x, argv)
- Xchar **argv;
- X{
- X int n = 0;
- X char *Cmds[50], *p, *malloc(), buf[30];
- X
- X if (!*++argv) {
- X for (x = 0; cmds[x].command; x++) {
- X if (!(x % 5))
- X if (!(p = Cmds[n++] = malloc(80))) {
- X error("malloc in question_mark()");
- X free_vec(Cmds);
- X return -1;
- X }
- X p += strlen(sprintf(p, "%-11.11s ", cmds[x].command));
- X }
- X Cmds[n++] = savestr("Type: `command' -? for help with most commands.");
- X Cmds[n] = NULL;
- X (void) help(0, Cmds, NULL);
- X free_vec(Cmds);
- X } else {
- X for (x = 0; cmds[x].command; x++)
- X if (!strcmp(*argv, cmds[x].command))
- X return cmd_line(sprintf(buf, "%s -?", *argv), msg_list);
- X print("Unknown command: %s\n", *argv);
- X }
- X return -1;
- X}
- X
- X#ifdef SIGSTOP
- Xstop(argc, argv)
- Xchar **argv;
- X{
- X if (istool)
- X print("Not a tool-based option.");
- X if (argc && *++argv && !strcmp(*argv, "-?"))
- X return help(0, "stop", cmd_help);
- X if (kill(getpid(), SIGTSTP) == -1)
- X error("couldn't stop myself");
- X return -1;
- X}
- X#endif SIGSTOP
- X
- Xextern char **environ;
- Xstatic int spaces = 0;
- X
- XSetenv(i, argv)
- Xchar **argv;
- X{
- X char *newstr;
- X
- X if (i < 2 || i > 3 || !strcmp(argv[1], "-?"))
- X return help(0, "setenv", cmd_help);
- X
- X if (i == 3) {
- X newstr = malloc(strlen(argv[1]) + strlen(argv[2]) + 2);
- X (void) sprintf(newstr, "%s=%s", argv[1], argv[2]);
- X } else {
- X newstr = malloc(strlen(argv[1]) + 2);
- X (void) sprintf(newstr, "%s=", argv[1]);
- X }
- X
- X (void) Unsetenv(2, argv);
- X
- X for (i = 0; environ[i]; i++);
- X if (!spaces) {
- X char **new_environ = (char **)malloc((i+2) * sizeof(char *));
- X /* add 1 for the new item, and 1 for null-termination */
- X if (!new_environ) {
- X free(newstr);
- X return -1;
- X }
- X spaces = 1;
- X for (i = 0; new_environ[i] = environ[i]; i++);
- X xfree(environ);
- X environ = new_environ;
- X }
- X environ[i] = newstr;
- X environ[i+1] = NULL;
- X spaces--;
- X return -1;
- X}
- X
- XUnsetenv(n, argv)
- Xchar **argv;
- X{
- X char **envp, **last;
- X
- X if (n != 2 || !strcmp(argv[1], "-?"))
- X return help(0, "unsetenv", cmd_help);
- X
- X n = strlen(argv[1]);
- X for (last = environ; *last; last++);
- X last--;
- X
- X for (envp = environ; envp <= last; envp++) {
- X if (strncmp(argv[1], *envp, n) == 0 && (*envp)[n] == '=') {
- X xfree(*envp);
- X *envp = *last;
- X *last-- = NULL;
- X spaces++;
- X }
- X }
- X return -1;
- X}
- X
- XPrintenv()
- X{
- X char **e = environ;
- X while (*e)
- X wprint("%s\n", *e++);
- X return -1;
- X}
- X
- X/*
- X * internal stty call to allow the user to change his tty character
- X * settings. sorry, no way to change cbreak/echo modes. Save echo_flg
- X * so that execute() won't reset it.
- X */
- Xmy_stty(un_used, argv)
- Xchar **argv;
- X{
- X long save_echo = ison(glob_flags, ECHO_FLAG);
- X
- X turnon(glob_flags, ECHO_FLAG);
- X execute(argv);
- X if (save_echo)
- X turnon(glob_flags, ECHO_FLAG);
- X else
- X turnoff(glob_flags, ECHO_FLAG);
- X
- X savetty();
- X#ifdef TIOCGLTC
- X if (ioctl(0, TIOCGLTC, <chars))
- X error("TIOCGLTC");
- X#endif TIOCGLTC
- X echo_off();
- X return -1;
- X}
- END_OF_FILE
- if test 19548 -ne `wc -c <'commands.c'`; then
- echo shar: \"'commands.c'\" unpacked with wrong size!
- fi
- # end of 'commands.c'
- fi
- if test -f 'misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'misc.c'\"
- else
- echo shar: Extracting \"'misc.c'\" \(21487 characters\)
- sed "s/^X//" >'misc.c' <<'END_OF_FILE'
- X/* @(#)misc.c (c) copyright 10/18/86 (Dan Heller) */
- X
- X#include "mush.h"
- X
- X/* check to see if a string describes a message that is within the range of
- X * all messages; if invalid, return 0 and print error. else return msg number
- X */
- Xchk_msg(s)
- Xregister char *s;
- X{
- X register int n;
- X
- X if ((n = atoi(s)) > 0 && n <= msg_cnt)
- X return n;
- X else if (*s == '^' && msg_cnt)
- X return 1;
- X else if (*s == '$' && msg_cnt)
- X return msg_cnt;
- X else if (*s == '.' && msg_cnt)
- X return current_msg+1;
- X print("Invalid message number: %s\n", s);
- X return 0;
- X}
- X
- X/*
- X * loop thru all msgs starting with current_msg and find next message whose
- X * m_flags has the "flags" bit being on
- X */
- Xnext_msg(on, flags)
- X{
- X register int n = current_msg;
- X if (!msg_cnt)
- X return current_msg = 0;
- X for (n++; n != current_msg; n++)
- X if (n == msg_cnt) /* hit the end, start back at the beginning */
- X n = -1; /* increments to 0 in loop */
- X else if (isoff(msg[n].m_flags, DELETE) &&
- X ((on && ison(msg[n].m_flags, flags)) ||
- X (!on && isoff(msg[n].m_flags, flags))))
- X return current_msg = n;
- X return current_msg = 0;
- X}
- X
- X/* takes string 'p' and address of int (isdir). If p uses the ~ to reference
- X * a home directory of somesort, then expand it. find out what sort of
- X * file final path is. set isidr to 1 if a directory, 0 if not, -1 on error
- X * return final path. If an error occurrs, return string indicating error.
- X * if isdir has a value of 1 when passed, it ignores "No such file or directory"
- X */
- X#include <pwd.h>
- Xchar *
- Xgetpath(p, isdir)
- Xregister char *p;
- Xint *isdir;
- X{
- X static char buf[256];
- X struct stat stat_buf;
- X
- X if (!p || !*p || !strcmp(p, "~")) {
- X char *home = do_set(set_options, "home");
- X if (!home || !*home)
- X home = ALTERNATE_HOME;
- X (void) strcpy(buf, home); /* no arg means home */
- X } else if (*p == '~') {
- X if (p[1] != '/') {
- X /* not our home, but someone else's
- X * look for ~user or ~user/subpath
- X * if '/' exists, separate into tmp="user" p="subpath"
- X */
- X struct passwd *ent, *getpwnam();
- X char *p2 = p+1;
- X if (p = index(p2, '/'))
- X *p++ = 0;
- X if (!(ent = getpwnam(p2))) {
- X *isdir = -1;
- X return sprintf(buf, "no such user: %s", p2);
- X }
- X /* append subpath to pathname */
- X if (p && *p)
- X (void) sprintf(buf, "%s/%s", ent->pw_dir, p);
- X /* if *p == NULL, pathname is done (buf), set isdir = 1 */
- X else {
- X *isdir = 1;
- X return strcpy(buf, ent->pw_dir);
- X }
- X } else {
- X char *home = do_set(set_options, "home");
- X if (!home || !*home)
- X home = ALTERNATE_HOME;
- X (void) sprintf(buf, "%s/%s", home, p+2);
- X }
- X } else if (*p == '%') {
- X /* if %user, append user name... else, it's just us */
- X (void) sprintf(buf, "%s/", MAILDIR);
- X if (!*++p || *p == ' ' || *p == '\t')
- X (void) strcat(buf, login);
- X else
- X (void) strcat(buf, p);
- X } else if (*p == '+') {
- X register char *p2 = do_set(set_options, "folder");
- X if (p2 && *p2)
- X (void) sprintf(buf, "%s/%s", p2, ++p);
- X else
- X (void) sprintf(buf, "~/%s", p);
- X if (*buf == '~') {
- X int t_isdir = *isdir;
- X char *t, tmp[256];
- X (void) strcpy(tmp, buf);
- X t = getpath(tmp, &t_isdir);
- X if (t_isdir == -1) {
- X *isdir = -1;
- X return t;
- X }
- X /* strcpy(buf, t); --buf already has info because it's static */
- X }
- X } else { /* allow \ to escape the special chars, +, %, ~ */
- X if (*p == '\\')
- X p++;
- X (void) strcpy(buf, p);
- X }
- X if (stat(buf, &stat_buf)) {
- X (void) access(buf, 0); /* set errno to the "real" reason */
- X if (errno == ENOENT && *isdir == 1) {
- X *isdir = 0; /* say it's a regular file even tho it doesn't exist */
- X return buf; /* it may be wanted for creating */
- X }
- X *isdir = -1;
- X return sys_errlist[errno];
- X }
- X *isdir = ((stat_buf.st_mode & S_IFDIR) != 0);
- X return buf;
- X}
- X
- X/*
- X * Given a filename[pointer] (p), a file pointer, and a mode, file_to_fp
- X * opens the file with the mode.
- X * If the mode is "r" then we read the file into the file pointer at the
- X * end (fseek(fp, 2, 0)). If the file is opened for writing, then read
- X * from the beginning of fp and write it into the file.
- X * This is usually called to read .signatures into messages (thus,
- X * opening .signture with "r" and writing to the end of fp which is probably
- X * the sendmail process or the message file pointer) or to write fortunes into
- X * the message buffer: reading fp (the popened fortune) and writing into file.
- X */
- Xvoid
- Xfile_to_fp(p, fp, mode)
- Xregister char *p;
- Xregister FILE *fp;
- Xchar *mode;
- X{
- X int x = 1;
- X char *file, buf[BUFSIZ];
- X FILE *tmp_fp;
- X
- X if (!p || !*p) {
- X print("specify filename");
- X return;
- X }
- X file = getpath(p, &x);
- X if (x == -1) { /* on error, file contains error message */
- X wprint(file);
- X return;
- X }
- X wprint("%s: ", file), fflush(stdout);
- X if (x) /* if x == 1, then path is a directory */
- X wprint("directory.\n");
- X else if (!(tmp_fp = fopen(file, mode))) {
- X wprint("%s\n", sys_errlist[errno]);
- X return;
- X } else if (*mode != 'r') {
- X rewind(fp);
- X for(x = 0; fgets(buf, BUFSIZ, fp); x++)
- X fputs(buf, tmp_fp);
- X } else
- X for(x = 0; fgets(buf, BUFSIZ, tmp_fp); x++)
- X fputs(buf, fp);
- X wprint("%s%d line%s\n", (*mode == 'a')? "added ": "",
- X x, (x == 1)? "": "s");
- X fflush(fp);
- X fclose(tmp_fp);
- X}
- X
- X/*
- X * lose the newline character, trailing whitespace, and return the end of p
- X * test for '\n' separately since some _ctype_[] arrays may not have the
- X * _S bit set for the newline character. see <ctype.h> for more info.
- X */
- Xchar *
- Xno_newln(p)
- Xregister char *p;
- X{
- X register char *p2 = p + strlen(p); /* point it to the null terminator */
- X
- X while (p2 > p && *--p2 == '\n' || isspace(*p2))
- X *p2 = 0; /* get rid of newline and trailing spaces */
- X return p2;
- X}
- X
- X/* find any character in string2 that's in string1 */
- Xchar *
- Xany(s1, s2)
- Xregister char *s1, *s2;
- X{
- X register char *p;
- X if (!s1 || !*s1 || !s2 || !*s2)
- X return NULL;
- X for( ; *s1; s1++) {
- X for(p = s2; *p; p++)
- X if (*p == *s1)
- X return s1;
- X }
- X return NULL;
- X}
- X
- X/* since print_help just prints help, always return help() */
- Xprint_help(argc, argv)
- Xregister char **argv;
- X{
- X#ifdef SUNTOOL
- X if (istool)
- X return help(tool->tl_windowfd, "general", tool_help);
- X#endif SUNTOOL
- X if (!argc || !*++argv)
- X return help(0, "general", cmd_help);
- X return help(0, *argv, cmd_help);
- X}
- X
- X/* since this function does not affect messages, return -1 */
- Xhelp(fd, str, file)
- X#ifdef SUNTOOL
- Xcaddr_t *str;
- X#else
- Xchar *str;
- X#endif /* SUNTOOL */
- Xchar *file;
- X{
- X#ifdef SUNTOOL
- X if (istool > 1) {
- X int oldmask;
- X if (!fd)
- X fd = print_sw->ts_windowfd;
- X oldmask = sigblock(1 << ((SIGALRM) - 1));
- X lock_cursors();
- X if (display_help(fd, str, file, fonts[LARGE]) && file)
- X error("can't read %s", file);
- X unlock_cursors();
- X (void) sigsetmask(oldmask);
- X } else
- X#endif SUNTOOL
- X if (find_help(str, file) && file)
- X error("can't read %s", file);
- X return -1; /* doesn't affect any messages */
- X}
- X
- X#ifdef SUNTOOL
- Xvoid
- Xunlock_cursors()
- X{
- X if (istool < 2)
- X return;
- X win_setcursor(print_sw->ts_windowfd, &main_cursor);
- X win_setcursor(panel_sw->ts_windowfd, &main_cursor);
- X if (getting_opts)
- X win_setcursor(msg_sw->ts_windowfd, &checkmark);
- X else if (ison(glob_flags, IS_GETTING))
- X win_setcursor(msg_sw->ts_windowfd, &write_cursor);
- X else
- X win_setcursor(msg_sw->ts_windowfd, &read_cursor);
- X win_setcursor(hdr_panel_sw->ts_windowfd, &main_cursor);
- X win_setcursor(hdr_sw->ts_windowfd, &l_cursor);
- X}
- X
- Xvoid
- Xlock_cursors()
- X{
- X if (istool < 2)
- X return;
- X win_setcursor(hdr_sw->ts_windowfd, &coffee);
- X win_setcursor(print_sw->ts_windowfd, &coffee);
- X win_setcursor(panel_sw->ts_windowfd, &coffee);
- X win_setcursor(msg_sw->ts_windowfd, &coffee);
- X win_setcursor(hdr_panel_sw->ts_windowfd, &coffee);
- X}
- X
- X#include <suntool/fullscreen.h>
- X/* return the event-id that confirmed */
- Xconfirm(fd)
- X{
- X struct fullscreen *fs;
- X
- X struct inputmask im;
- X struct inputevent event;
- X
- X fs = fullscreen_init(fd);
- X input_imnull(&im);
- X im.im_flags |= IM_ASCII;
- X win_setinputcodebit(&im, MS_LEFT);
- X win_setinputcodebit(&im, MS_MIDDLE);
- X win_setinputcodebit(&im, MS_RIGHT);
- X win_setinputmask(fd, &im, &im, WIN_NULLLINK);
- X win_setcursor(fd, &l_cursor);
- X if (input_readevent(fd, &event) == -1)
- X error("confim failed");
- X fullscreen_destroy(fs);
- X return ID;
- X}
- X#endif SUNTOOL
- X
- X/* check two lists of strings each of which contain substrings.
- X * Each substring is delimited by any char in "delimeters"
- X * return true if any elements in list1 are on list2.
- X * thus:
- X * string1 = "foo, bar, baz"
- X * string2 = "foobar, baz, etc"
- X * delimeters = ", \t"
- X * example returns 1 because "baz" exists in both lists
- X * NOTE: case is ignored.
- X */
- Xchk_two_lists(list1, list2, delimeters)
- Xregister char *list1, *list2, *delimeters;
- X{
- X register char *p, c;
- X register int found = 0;
- X
- X if (p = any(list1, delimeters)) {
- X for (p++; *p && index(delimeters, *p); p++)
- X ;
- X if (chk_two_lists(p, list2, delimeters))
- X return 1;
- X }
- X if (p = any(list2, delimeters)) {
- X for (p++; *p && index(delimeters, *p); p++)
- X ;
- X if (chk_two_lists(list1, p, delimeters))
- X return 1;
- X }
- X if (p) {
- X while (index(delimeters, *(p-1)))
- X --p;
- X c = *p, *p = 0;
- X }
- X found = !lcase_strcmp(list1, list2);
- X if (p)
- X *p = c;
- X return found;
- X}
- X
- Xbzero(addr, size)
- Xregister char *addr;
- Xregister int size;
- X{
- X while (size-- > 0)
- X addr[size] = 0;
- X}
- X
- X/* see if there are at least Max lines in this file. return lines less than Max
- X * that actually *are* in the file
- X */
- Xlines_in(fp, Max)
- Xregister FILE *fp;
- Xregister int Max;
- X{
- X char tmp[BUFSIZ];
- X long place_in_fp = ftell(fp);
- X rewind(fp);
- X while (Max > 0 && fgets(tmp, BUFSIZ, fp))
- X Max--;
- X (void) fseek(fp, place_in_fp, 0);
- X return Max;
- X}
- X
- X/* clear all contents of the file. Careful that the file is opened for
- X * _writing_ --tempfile is opened for reading, so don't try to empty it
- X * if you're using ftruncate. Return -1 on error, 0 on success.
- X */
- Xemptyfile(fp, fname)
- Xregister FILE **fp;
- Xregister char *fname;
- X{
- X Debug("Emptying \"%s\"\n", fname);
- X#ifndef SYSV
- X return ftruncate(fileno(*fp), 0);
- X#else
- X {
- X int omask = umask(077), ret;
- X fclose(*fp);
- X if (!(*fp = fopen(fname, "w")))
- X ret = -1;
- X ret = 0;
- X (void) umask(omask);
- X return ret;
- X }
- X#endif SYSV
- X}
- X
- X/* do an atoi() on the string passed and return in "val" the decimal value.
- X * the function returns a pointer to the location in the string that is not
- X * a digit.
- X */
- Xchar *
- Xmy_atoi(p, val)
- Xregister char *p;
- Xregister int *val;
- X{
- X if (!p)
- X return NULL;
- X *val = 0;
- X while (isdigit(*p))
- X *val = (*val) * 10 + *p++ - '0';
- X return p;
- X}
- X
- X/* strcmp ignoring case */
- Xlcase_strcmp(str1, str2)
- Xregister char *str1, *str2;
- X{
- X while (*str1 && *str2)
- X if (lower(*str1) != lower(*str2))
- X break;
- X else
- X str1++, str2++;
- X return *str1 - *str2;
- X}
- X
- X/* strcpy coverting everything to lower case (arbitrary) to ignore cases */
- Xchar *
- Xlcase_strcpy(dst, src)
- Xregister char *dst, *src;
- X{
- X register char *s = dst;
- X
- X /* "lower" is a macro, don't incrment its argument! */
- X while (*dst++ = lower(*src))
- X src++;
- X return s;
- X}
- X
- X/* this strcpy returns number of bytes copied */
- XStrcpy(dst, src)
- Xregister char *dst, *src;
- X{
- X register int n = 0;
- X if (!dst || !src)
- X return 0;
- X while (*dst++ = *src++)
- X n++;
- X return n;
- X}
- X
- Xvoid
- Xxfree(cp)
- Xchar *cp;
- X{
- X extern char end[];
- X
- X if (cp >= end && cp < (char *) &cp && debug < 2)
- X free(cp);
- X}
- X
- Xchar *
- Xsavestr(s)
- Xregister char *s;
- X{
- X register char *p;
- X char *malloc();
- X if (!s)
- X s = "";
- X if (!(p = malloc((unsigned) (strlen(s) + 1)))) {
- X error("out of memory saving %s", s);
- X return NULL;
- X }
- X return strcpy(p, s);
- X}
- X
- Xvoid
- Xfree_vec(argv)
- Xchar **argv;
- X{
- X register int n;
- X if (!argv)
- X return;
- X for (n = 0; argv[n]; n++)
- X xfree(argv[n]);
- X xfree((char *)argv);
- X}
- X
- X/* copy a vector of stirngs into one string -- return the end of the string */
- Xchar *
- Xargv_to_string(p, argv)
- Xregister char *p, **argv;
- X{
- X register int i;
- X register char *ptr = p;
- X
- X *p = 0;
- X if (!argv[0])
- X return "";
- X for (i = 0; argv[i]; i++)
- X ptr += strlen(sprintf(ptr, "%s ", argv[i]));
- X *--ptr = 0; /* get rid of the last space */
- X return ptr;
- X}
- X
- X/* echo the command line. return -1 cuz no messages are affected */
- Xdo_echo(argc, argv)
- Xregister char **argv;
- X{
- X char buf[BUFSIZ];
- X int no_return;
- X
- X if (argc > 1 && !strcmp(argv[1], "-?")) {
- X print("usage: %s [-n] ...\n", *argv);
- X return -1;
- X }
- X no_return = *++argv && !strcmp(*argv, "-n");
- X (void) argv_to_string(buf, argv+no_return);
- X print("%s%s", buf, (no_return)? "" : "\n");
- X return -1;
- X}
- X
- X/* return -1 on error or number of arguments in argv that were parsed */
- Xget_msg_list(argv, list)
- Xregister char **argv;
- Xchar list[];
- X{
- X register char *p2, *p;
- X char buf[256];
- X register int n;
- X
- X if (!msg_cnt) {
- X print("No messages.\n");
- X return -1;
- X }
- X if (!argv || !*argv) {
- X if (isoff(glob_flags, IS_PIPE))
- X set_msg_bit(list, current_msg);
- X return 0;
- X }
- X /* first, stuff argv's args into a single char array buffer */
- X (void) argv_to_string(buf, argv);
- X p = buf;
- X Debug("get_msg_list: parsing: (%s): ", p);
- X /*
- X * if do_range returns NULL, an invalid message was specified
- X */
- X if (!(p2 = do_range(p, list)))
- X return -1;
- X /*
- X * if p2 == p (and p isn't $ or ^ or .), then no message list was
- X * specified. set the current message in such cases if we're not piping
- X */
- X if (p2 == p) {
- X if (*p == '$')
- X set_msg_bit(list, msg_cnt-1);
- X else if (*p == '^')
- X set_msg_bit(list, 0);
- X else if (*p == '.' || isoff(glob_flags, IS_PIPE))
- X set_msg_bit(list, current_msg);
- X } else if (ison(glob_flags, IS_PIPE)) {
- X print("You can't pipe to a command *and* specifiy a msg_list\n");
- X return -1;
- X }
- X for (n = 0; p2 > p && *argv; n++)
- X p2 -= (strlen(*argv++)+1);
- X Debug("parsed %d args\n", n);
- X return n;
- X}
- X
- Xchar *
- Xitoa(n)
- X{
- X static char buf[10];
- X return sprintf(buf, "%d", n);
- X}
- X
- X#ifdef NOT_NEEDED_NOW
- X/* return whether or not this process is in the foreground or background */
- Xforeground()
- X{
- X#ifdef TIOCGPGRP
- X int tpgrp; /* short in 4.1, int in 4.2 */
- X
- X if (ioctl(0, TIOCGPGRP, (char *)&tpgrp))
- X return 0;
- X return tpgrp == getpgrp(0);
- X#else
- X return 1;
- X#endif TIOCGPGRP
- X}
- X#endif NOT_NEEDED_NOW
- X
- X#ifdef SYSV
- Xchar *
- XSprintf(buf, fmt, args)
- Xregister char *buf, *fmt;
- X{
- X vsprintf(buf, fmt, &args);
- X return buf;
- X}
- X#endif /* SYSV */
- X
- X/*
- X * Finds out how many file descriptors are opened. Useful for making sure
- X * no files got opened in subprocedures which were not subsequently closed.
- X */
- Xnopenfiles(argc)
- X{
- X register int nfiles = 0;
- X#ifdef MAXFILES
- X register int size = MAXFILES;
- X#else
- X register int size = getdtablesize();
- X#endif MAXFILES
- X
- X if (argc < 2)
- X print("open file descriptors:");
- X while (--size >= 0)
- X if (fcntl(size, F_GETFL, 0) != -1) {
- X if (argc < 2)
- X print_more(" %d", size);
- X ++nfiles;
- X }
- X if (argc < 2)
- X print("\n");
- X return nfiles;
- X}
- X
- X/*
- X * Open a path for writing or appending -- return a FILE pointer.
- X * If program is TRUE, then use popen, not fopen and don't check
- X * to see if the file is writable.
- X */
- XFILE *
- Xopen_file(p, program)
- Xregister char *p;
- X{
- X register FILE *newfile = NULL_FILE;
- X register char *tmp;
- X int x = 1;
- X
- X tmp = getpath(p, &x);
- X if (x == 1)
- X print("%s is a directory.\n", tmp);
- X else if (x == -1)
- X print("%s: %s\n", p, tmp);
- X else {
- X register char *mode = NULL;
- X /* if it doesn't exist open for "w" */
- X if (program || access(tmp, 0))
- X mode = "w";
- X /* if we can't write to it, forget it */
- X else if (access(tmp, 2))
- X error(tmp);
- X else
- X mode = "a";
- X if (mode)
- X if (program) {
- X if (!(newfile = popen(tmp, mode))) {
- X error("Can't execute %s\n", tmp);
- X return newfile;
- X }
- X } else
- X if (!(newfile = fopen(tmp, mode)))
- X error("Can't write to %s", tmp);
- X else
- X Debug("Successfully opened %s\n", tmp);
- X }
- X return newfile;
- X}
- X
- X/*
- X * find_files gets a string of space/comma delimeted words and an array of
- X * file pointers and the maximum size that array can be.
- X * The object is to find the files or programs listed in "p", attempt
- X * to fopen/popen them and save their filepointers in the array. If the
- X * size is 0, then just extract the file names and give error messages
- X * for each one since they will not be opened. Return the number of
- X * files opened and delete all files (opened or not) from the list in
- X * "p". Tokens beginning with a "/, ~, or + are files; tokens beginning
- X * with a | are programs.
- X */
- Xfind_files(p, files, size)
- Xregister char *p;
- XFILE *files[];
- X{
- X register int total = 0;
- X char file[BUFSIZ], *start = p;
- X register char *p2, *s;
- X
- X for (s = p; p = any(s, "~+/|"); s = p) {
- X int prog = 0;
- X
- X /* If there is no space or comma before this address, then
- X * it's not the beginning of an address, but part of another.
- X * Ignore this addres and continue to the next in the list.
- X */
- X if (p > start && *(p-1) != ',' && !isspace(*(p-1))) {
- X p++; /* prevent inifinite loop -- resume starting at next char */
- X continue;
- X }
- X
- X /* get the whole filename, stick it in "file" */
- X if (p2 = any(p, ", \t"))
- X *p2++ = '\0';
- X else
- X p2 = p + strlen(p);
- X (void) strcpy(file, p);
- X /* overwrite the filename in the string with whatever proceeds it */
- X while (isspace(*p2)) /* move to the next address (or end of string) */
- X p2++;
- X if (*p2)
- X (void) strcpy(p, p2);
- X else
- X do
- X *p = '\0';
- X while (--p >= start && (isspace(*p) || *p == ','));
- X
- X if (*file == '|')
- X prog = 1; /* it's a program name */
- X if (size && total < size) {
- X /* either open "file" or &file[1] */
- X if (files[total] = open_file(&file[prog], prog))
- X total++;
- X } else
- X print("No open space for %s\n", file);
- X skipspaces(0);
- X }
- X return total;
- X}
- X
- X/*
- X * execute a command from a string. f'rinstance: "pick -f foobar"
- X * The string is made into an argv and then run. Errors are printed
- X * if the command failed to make.
- X * NOTES:
- X * NEVER pass stright text: e.g. "pick -f foobar", ALWAYS strcpy(buf, "...")
- X * no history is expanded (ignore_bang).
- X */
- Xcmd_line(buf, list)
- Xchar buf[], list[];
- X{
- X register char **argv;
- X int argc, ret_val = -1;
- X long save_bang = ison(glob_flags, IGN_BANG);
- X long save_do_pipe = ison(glob_flags, DO_PIPE);
- X long save_is_pipe = ison(glob_flags, IS_PIPE);
- X
- X turnon(glob_flags, IGN_BANG);
- X turnoff(glob_flags, DO_PIPE);
- X turnoff(glob_flags, IS_PIPE);
- X if (argv = make_command(buf, TRPL_NULL, &argc))
- X ret_val = do_command(argc, argv, list);
- X if (!save_bang)
- X turnoff(glob_flags, IGN_BANG);
- X if (save_do_pipe)
- X turnon(glob_flags, DO_PIPE);
- X if (save_is_pipe)
- X turnon(glob_flags, IS_PIPE);
- X return ret_val;
- X}
- X
- Xglob_test(s)
- Xchar *s;
- X{
- X print("%s: glob_flags =", s);
- X if (ison(glob_flags, DO_UPDATE))
- X print_more(" DO_UPDATE");
- X if (ison(glob_flags, REV_VIDEO))
- X print_more(" REV_VIDEO");
- X if (ison(glob_flags, CONT_PRNT ))
- X print_more(" CONT_PRNT");
- X if (ison(glob_flags, DO_SHELL ))
- X print_more(" DO_SHELL");
- X if (ison(glob_flags, DO_PIPE))
- X print_more(" DO_PIPE");
- X if (ison(glob_flags, IS_PIPE))
- X print_more(" IS_PIPE");
- X if (ison(glob_flags, IGN_SIGS))
- X print_more(" IGN_SIGS");
- X if (ison(glob_flags, IGN_BANG))
- X print_more(" IGN_BANG");
- X if (ison(glob_flags, ECHO_FLAG))
- X print_more(" ECHO_FLAG");
- X if (ison(glob_flags, IS_GETTING))
- X print_more(" IS_GETTING");
- X if (ison(glob_flags, PRE_CURSES))
- X print_more(" PRE_CURSES");
- X if (ison(glob_flags, READ_ONLY ))
- X print_more(" READ_ONLY");
- X if (ison(glob_flags, REDIRECT))
- X print_more(" REDIRECT");
- X if (ison(glob_flags, WAS_INTR ))
- X print_more(" WAS_INTR");
- X if (ison(glob_flags, WARNING ))
- X print_more(" WARNING");
- X print_more("\n");
- X}
- X
- Xis_spool(f)
- Xregister char *f;
- X{
- X return !strncmp(f, MAILDIR, strlen(MAILDIR));
- X}
- X
- Xprint_argv(argv)
- Xchar **argv;
- X{
- X while (*argv)
- X if (debug)
- X printf("(%s) ", *argv++);
- X else
- X wprint("%s ", *argv++);
- X if (debug) {
- X putchar('\n');
- X fflush(stdout);
- X } else
- X wprint("\n");
- X}
- X
- Xmsg_flags(c, v, list)
- Xregister char **v, *list;
- X{
- X register int i;
- X register long newflag = 0;
- X
- X if (c && *++v && !strcmp(*v, "-?"))
- X return help(0, "msg_flags", cmd_help);
- X if (c && (c = get_msg_list(v, list)) == -1)
- X return -1;
- X if (v && *(v += (c-1))) {
- X turnon(glob_flags, DO_UPDATE);
- X while (*++v)
- X for (c = 0; v[0][c]; c++)
- X switch (lower(v[0][c])) {
- X case 'n' : turnon(newflag, UNREAD), turnoff(newflag, OLD);
- X when 'o' : turnon(newflag, OLD);
- X when 'r' : turnoff(newflag, UNREAD);
- X when 'd' : turnon(newflag, DELETE);
- X when 'p' : turnon(newflag, PRESERVE);
- X when 'u' : turnon(newflag, UNREAD);
- X otherwise: return help(0, "msg_flags", cmd_help);
- X }
- X }
- X
- X for (i = 0; i < msg_cnt; i++) {
- X if (!msg_bit(list, i))
- X continue;
- X else if (!newflag) {
- X wprint("msg %d: offset: %d, lines: %d, bytes: %d, flags:", i+1,
- X msg[i].m_offset, msg[i].m_lines, msg[i].m_size);
- X if (ison(msg[i].m_flags, UNREAD))
- X wprint(" UNREAD");
- X if (ison(msg[i].m_flags, OLD))
- X wprint(" OLD");
- X if (ison(msg[i].m_flags, DELETE))
- X wprint(" DELETE");
- X if (ison(msg[i].m_flags, PRESERVE))
- X wprint(" PRESERVE");
- X if (ison(msg[i].m_flags, UPDATE_STATUS))
- X wprint(" UPDATE_STATUS");
- X wprint("\n");
- X } else
- X msg[i].m_flags = newflag;
- X }
- X return 0;
- X}
- END_OF_FILE
- if test 21487 -ne `wc -c <'misc.c'`; then
- echo shar: \"'misc.c'\" unpacked with wrong size!
- fi
- # end of 'misc.c'
- fi
- echo shar: End of archive 7 \(of 12\).
- cp /dev/null ark7isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 12 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-